// EditHistory.cpp: implementation of the CEditHistory class.
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "ansieditor.h"
#include "EditHistory.h"

#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

CEditHistory::CEditHistory(CAnsiPage *pAnsiPage)
{
	m_nCurStep = m_nTopStep = -1;
	m_pPage = pAnsiPage;
//	afxDump << m_pPage->m_chars[0][0] << "###\n";
}

CEditHistory::~CEditHistory()
{
	Clear();
}

void CEditHistory::Clear()
{
	int nCount = m_arrStep.GetSize();
	for(int n = 0; n < nCount; n++)
	{
		delete m_arrStep.GetAt(n);
	}
	m_arrStep.RemoveAll();
	m_nTopStep = m_nCurStep = -1;
}

BOOL CEditHistory::CanUndo()
{
	return m_nCurStep != -1;
}

BOOL CEditHistory::CanRedo()
{
	return m_nCurStep < m_nTopStep;
}

void CEditHistory::Undo()
{
	if(!CanUndo())
	{
		return;
	}
	m_arrStep.GetAt(m_nCurStep)->Restore();
	--m_nCurStep;
}

void CEditHistory::Redo()
{
	if(!CanRedo())
	{
		return;
	}
	++m_nCurStep;
	m_arrStep.GetAt(m_nCurStep)->Restore();
}

CEditStep* CEditHistory::Add(int nCursorX, int nCursorY)
{
	CEditStep *pEditStep = GetCurStep();
	if(pEditStep)
	{
		if(pEditStep->IsEmpty())
		{
			pEditStep->SaveCursorPos(nCursorX, nCursorY);
			return pEditStep;
		}
		else
		{
			pEditStep->Compact();
		}
	}
	++m_nCurStep;
	for(int n = m_nCurStep; n <= m_nTopStep; n++)
	{
		delete m_arrStep.GetAt(n);
	}
	if(m_nCurStep <= m_nTopStep)
	{
		m_arrStep.RemoveAt(m_nCurStep, m_nTopStep - m_nCurStep + 1);
	}
	m_nTopStep = m_nCurStep;
//	afxDump << m_pPage->m_chars[0][0] << "###\n";
	pEditStep = new CEditStep(m_pPage);
	pEditStep->SaveCursorPos(nCursorX, nCursorY);
	m_arrStep.Add(pEditStep);
	return pEditStep;
}

CEditStep* CEditHistory::GetCurStep()
{
	if(m_nCurStep == -1)
	{
		return NULL;
	}
	return m_arrStep.GetAt(m_nCurStep);
}

void CEditHistory::CancelCurStep()
{
	if(m_nCurStep != m_nTopStep || m_nCurStep == -1)
	{
		ASSERT(FALSE);
		return;
	}
	--m_nCurStep;
	delete m_arrStep.GetAt(m_nTopStep);
	m_arrStep.RemoveAt(m_nTopStep);
	m_nTopStep = m_nCurStep;
}

int CEditHistory::GetStepCount()
{
	return m_arrStep.GetSize();
}
